import argparse
import os
import sys
import traceback
from multiprocessing import cpu_count
from multiprocessing.pool import ThreadPool
from threading import Lock
from typing import BinaryIO

from win2xcur.parser import open_blob
from win2xcur.writer.CPictureFormats import to_gif, to_png, to_pngs


def main() -> None:
    parser = argparse.ArgumentParser(description='Converts Windows cursors to images.')
    parser.add_argument('files', type=argparse.FileType('rb'), nargs='+',
                        help='Windows cursor files to convert (*.ani)')
    parser.add_argument('-o', '--output', '--output-dir', default=os.curdir,
                        help='Directory to store converted cursor files.')
    parser.add_argument('-T', '--type', default="gif",
                        help='Output files formats (*.png, *.gif).')

    args = parser.parse_args()
    print_lock = Lock()

    def process(file: BinaryIO) -> None:
        name = file.name
        blob = file.read()
        try:
            cursor = open_blob(blob)
        except Exception:
            with print_lock:
                print(f'Error occurred while processing {name}:', file=sys.stderr)
                traceback.print_exc()
        else:
            if args.type == "gif":
                imgs, speed = to_gif(cursor.frames)
                if args.output.endswith(".gif"):
                    imgs[0].save(args.output, save_all=True, append_images=imgs, loop=0, duration=speed,transparency=0,disposal=3)
                else:
                    output = os.path.join(args.output, os.path.splitext(os.path.basename(name))[0]) + ".gif"
                    imgs[0].save(output, save_all=True, append_images=imgs, loop=0, duration=speed,transparency=0,disposal=3)
            elif args.type == "png":
                result = to_pngs(cursor.frames)
                for i in range(len(result)):
                    output = os.path.join(args.output, os.path.splitext(os.path.basename(name))[0])+str(i) + ".png"
                    with open(output, "wb") as f:
                        f.write(result[i])
            elif args.type == "apng":
                result = to_png(cursor.frames)
                if args.output.endswith(".png"):
                    result.save(args.output, "png")
                else:
                    output = os.path.join(args.output, os.path.splitext(os.path.basename(name))[0]) + ".png"
                    result.save(output, "png")

    with ThreadPool(cpu_count()) as pool:
        pool.map(process, args.files)


if __name__ == '__main__':
    main()
